﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Security.AccessControl;
using System.Threading.Tasks;
using DnsClient.Internal;
using EventBus.Extensions;
using HttpLib.Services;
using Location.API.Infrastructure.Services;
using Location.API.Model;
using Location.API.ViewModel;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using RabbitMQ.Client;

namespace Location.API.Controllers
{
    [Route("api/v1/[controller]")]
    [ApiController]
    [Authorize]
    public class LocationsController : ControllerBase
    {
        private readonly ILocationsService _locationsService;
        private readonly IIdentityService _identityService;
        private readonly ILogger<LocationsController> _logger;
        public LocationsController(
            ILocationsService locationsService,
            IIdentityService identityService,
            ILogger<LocationsController> logger)
        {
            _locationsService = locationsService ?? throw new ArgumentNullException(nameof(locationsService));
            _identityService = identityService ?? throw new ArgumentNullException(nameof(identityService));
            _logger = logger ?? throw new ArgumentNullException(nameof(logger));
        }
        /// <summary>
        /// 获取位置
        /// </summary>
        /// <param name="locationId"></param>
        /// <returns></returns>
        [Route("{id}")]
        [HttpGet]
        [ProducesResponseType(typeof(Locations), (int)HttpStatusCode.OK)]
        public async Task<ActionResult<Locations>> GetLocationsAsync(string locationId)
        {
            return await _locationsService.GetLocationsAsync(locationId);
        }
        /// <summary>
        /// 获取用户位置
        /// </summary>
        /// <param name="userId"></param>
        /// <returns></returns>
        [Route("user/address")]
        [HttpGet]
        [ProducesResponseType(typeof(IEnumerable<UserLocationResponse>), (int)HttpStatusCode.OK)]
        public async Task<ActionResult<IEnumerable<UserLocationResponse>>> GetUserLocationAsync()
        {
            string userId = _identityService.GetUserIdentity();
            var locations = await _locationsService.GetUserLocationAsync(userId);
            return Ok(locations);
        }
        /// <summary>
        /// 新增用户位置
        /// </summary>
        /// <param name="location"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("user/address")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> AddUserLocationAsync([FromBody]UserLocationRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                Locations locations = new Locations(request.Province,request.City,request.District,request.DetailedAddress,request.Phone,request.Description,request.Longitude,request.Latitude,request.Remark);
                await _locationsService.AddUserLocationAsync(userId, locations);
                _logger.LogInformation(
                "----- Add UpdateUserLocation Succeed: {UserLocation} - {IdProperty}: {LocationId} ({@Locations})",
                locations.GetGenericTypeName(),
                nameof(locations.Id),
                locations.Id,
                locations);
                return Ok();
            }
            catch(Exception e)
            {
                _logger.LogError($"----- Add UpdateUserLocation Error,Message:{e.Message},parameter:{request}");
                return BadRequest();
            }
        }
        /// <summary>
        /// 更新用户位置
        /// </summary>
        /// <param name="locationId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("user/address")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> UpdateUserLocationAsync([FromBody]UserLocationRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                var location = await _locationsService.GetLocationsAsync(request.LocationId);
                if (location == null)
                    return BadRequest();
                location.Province = request.Province;
                location.City = request.City;
                location.District = request.District;
                location.Phone = request.Phone;
                location.DetailedAddress = request.DetailedAddress;
                location.Description = request.Description;
                location.Latitude = request.Latitude;
                location.Longitude = request.Longitude;
                location.Remark = request.Remark;
                await _locationsService.UpdateUserLocationAsync(userId, location);
                _logger.LogInformation(
                "----- Update UpdateUserLocation Succeed: {UserLocation} - {IdProperty}: {LocationId} ({@Locations})",
                location.GetGenericTypeName(),
                nameof(location.Id),
                location.Id,
                location);
                return Ok();
            }
            catch(Exception e)
            {
                _logger.LogError($"----- Update Locations Error,LocationId{request.LocationId},Error Message:{e.Message}");
                return BadRequest();
            }
        }
        [HttpDelete]
        [Route("user/address/{id}")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> DeleteUserLocationAsync(string id)
        {
            string userId = _identityService.GetUserIdentity();
            var location = await _locationsService.GetLocationsAsync(id);
            if(location != null)
            {
                location.IsRemove = true;
                await _locationsService.UpdateUserLocationAsync(userId, location);
                return Ok();
            }
            else
            {
                return BadRequest();
            }

        }
        /// <summary>
        /// 获取小区位置
        /// </summary>
        /// <param name="residentialAreasId"></param>
        /// <returns></returns>
        [HttpGet]
        [Route("areaslocation/{residentialAreasId}")]
        [ProducesResponseType(typeof(Locations), (int)HttpStatusCode.OK)]
        public async Task<ActionResult<Locations>> GetResidentialAreasLocationAsync(string residentialAreasId)
        {
            var locations = await _locationsService.GetResidentialAreasLocationAsync(residentialAreasId);
            return Ok(locations);
        }
        /// <summary>
        /// 新增小区位置
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("areaslocation")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<ActionResult> AddResidentialAreasLocationAsync([FromBody]ResidentialAreasLocationRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                Locations locations = new Locations(request.Province,request.City,request.District,request.DetailedAddress,request.Phone,request.Description, request.Longitude, request.Latitude, request.Remark);
                await _locationsService.AddResidentialAreasLocationAsync(request.ResidentialAreasLocationId, locations);
                _logger.LogInformation(
                "----- Add ResidentialAreasLocation Succeed: {ResidentialAreasLocation} - {IdProperty}: {LocationId} ({@Locations})",
                locations.GetGenericTypeName(),
                nameof(locations.Id),
                locations.Id,
                locations);
                return Ok();
            }
            catch(Exception e)
            {
                _logger.LogError($"----- Add ResidentialAreasLocation Error,Message:{e.Message},parameter:{request}");
                return BadRequest();
            }
        }

        /// <summary>
        /// 更新小区位置
        /// </summary>
        /// <param name="locationId"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("areaslocation")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> UpdateResidentialAreasLocationAsync([FromBody] ResidentialAreasLocationRequest request)
        {
            try
            {
                //string userId = _identityService.GetUserIdentity();
                var location = await _locationsService.GetLocationsAsync(request.LocationId);
                location.Description = request.Description;
                location.Latitude = request.Latitude;
                location.Longitude = request.Longitude;
                location.Province = request.Province;
                location.City = request.City;
                location.District = request.District;
                location.Phone = request.Phone;
                location.DetailedAddress = request.DetailedAddress;
                location.Remark = request.Remark;
                await _locationsService.UpdateResidentialAreasLocationAsync(request.ResidentialAreasLocationId, location);
                _logger.LogInformation(
                "----- Update ResidentialAreasLocation Succeed: {ResidentialAreasLocation} - {IdProperty}: {LocationId} ({@Locations})",
                location.GetGenericTypeName(),
                nameof(location.Id),
                location.Id,
                location);
                return Ok();
            }
            catch (Exception e)
            {
                _logger.LogError($"----- Update ResidentialAreasLocation Error,LocationId{request.LocationId},Error Message:{e.Message}");
                return BadRequest();
            }
        }
        [HttpGet]
        [Route("storelocation/{expressStoreLocationId}")]
        [ProducesResponseType(typeof(Locations), (int)HttpStatusCode.OK)]
        public async Task<ActionResult<Locations>> GetExpressStoreLocationAsync(string expressStoreLocationId)
        {
            var locations = await _locationsService.GetExpressStoreLocationAsync(expressStoreLocationId);
            return Ok(locations);
        }
        /// <summary>
        /// 新增快递店地址
        /// </summary>
        /// <param name="expressStoreId"></param>
        /// <param name="location"></param>
        /// <returns></returns>
        [HttpPost]
        [Route("storelocation")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> AddExpressStoreLocationAsync([FromBody]ExpressStoreLocationRequest request)
        {
            try
            {
                string userId = _identityService.GetUserIdentity();
                Locations locations = new Locations(request.Province, request.City, request.District, request.DetailedAddress, request.Phone,request.Description, request.Longitude, request.Latitude, request.Remark);
                await _locationsService.AddExpressStoreLocationAsync(request.ExpressStoreId, locations);
                _logger.LogInformation(
                "----- Add ExpressStoreLocation Succeed: {ExpressStoreLocation} - {IdProperty}: {LocationId} ({@ExpressStoreLocation})",
                locations.GetGenericTypeName(),
                nameof(locations.Id),
                locations.Id,
                locations);
                return Ok();
            }
            catch (Exception e)
            {
                _logger.LogError($"----- Add ExpressStoreLocation Error,Message:{e.Message},parameter:{request}");
                return BadRequest();
            }
        }
        /// <summary>
        /// 更新快递地址
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        [HttpPut]
        [Route("storelocation")]
        [ProducesResponseType((int)HttpStatusCode.OK)]
        [ProducesResponseType((int)HttpStatusCode.BadRequest)]
        public async Task<IActionResult> UpdateExpressStoreLocationAsync([FromBody] ExpressStoreLocationRequest request)
        {
            try
            {
                var location = await _locationsService.GetLocationsAsync(request.LocationId);
                location.Description = request.Description;
                location.Latitude = request.Latitude;
                location.Longitude = request.Longitude;
                location.Province = request.Province;
                location.City = request.City;
                location.District = request.District;
                location.Phone = request.Phone;
                location.DetailedAddress = request.DetailedAddress;
                location.Remark = request.Remark;
                await _locationsService.UpdateExpressStoreLocationAsync(request.ExpressStoreId, location);
                _logger.LogInformation(
                "----- Update ExpressStoreLocation Succeed: {ExpressStoreLocation} - {IdProperty}: {LocationId} ({@Locations})",
                location.GetGenericTypeName(),
                nameof(location.Id),
                location.Id,
                location);
                return Ok();
            }
            catch (Exception e)
            {
                _logger.LogError($"----- Update ExpressStoreLocation Error,LocationId{request.LocationId},Error Message:{e.Message}");
                return BadRequest();
            }
        }
    }
}
